/**
 * 项目名：	Rumba Plan
 * 
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2006，所有权利保留。
 * 
 * 文件名：	Progress.java
 * 模块说明：	
 * 修改历史：
 * 2006-10-27 - lxm - 创建。
 */
package com.hd123.rumba.runtime.backprocess;

import java.util.ArrayList;
import java.util.List;

/**
 * 处理进度 | 实现类
 * <p>
 * 
 * 其中包括了对一个处理的进程情况的查询和设置。
 * 
 * @author lxm
 * 
 */
public class Progress {

  /** 标题 */
  private String caption = null;
  /** 最小值 */
  private float minValue = 0;
  /** 最大值 */
  private float maxValue = 100;
  /** 当前进度位置 */
  private float position = 0;
  /** 换算成上级步长。表示当前进度全部完成相当于完成上级进度的步长。 */
  private float parentStep;
  /** 消息前缀 */
  private String msgPrefix;

  /** 所属栈。 */
  private ProgressStack stack;
  /** 当前进度的上一条消息 */
  private String lastMessage = null;
  /** 消息列表 */
  private List<String> messages = new ArrayList();

  public Progress(ProgressStack stack) {
    super();
    this.stack = stack;
  }

  /**
   * 设置进度前进指定的步长。
   * 
   * @param step
   *          步长。
   * @throws InterruptedException
   */
  public synchronized void stepBy(float step) throws InterruptedException {
    Thread.sleep(0);
    this.position += step;
    if (this.position > this.maxValue)
      this.position = this.maxValue;
    if (this.getParent() != null)
      this.getParent().stepBy(step * this.parentStep / (this.maxValue - this.minValue));
  }

  /**
   * 取得当前的百分比进度。
   * 
   * @return
   */
  public float getPercent() {
    return (this.position - this.minValue) * 100 / (this.maxValue - this.minValue);
  }

  /**
   * 取得当前最新的消息。
   * 
   * @return 返回当前最新的消息，若没有任何历史消息则返回null。
   */
  public String getMessage() {
    return this.lastMessage;
  }

  /**
   * 加入一条消息。<br>
   * 将自动调用finishChild，强制结束当前子进度。
   * 
   * @param message
   *          被加入的消息。
   * @throws InterruptedException
   */
  public synchronized void putMessage(String message) throws InterruptedException {
    Thread.sleep(0);
    String msg = message;
    if (this.msgPrefix != null)
      msg = this.msgPrefix + msg;
    this.lastMessage = msg;
    this.messages.add(msg);
    if (this.getParent() != null)
      this.getParent().putMessage2("  " + msg);
  }
  
  private synchronized void putMessage2(String message) throws InterruptedException {
    Thread.sleep(0);
    String msg = message;
    if (this.msgPrefix != null)
      msg = this.msgPrefix + msg;
    this.messages.add(msg);
    if (this.getParent() != null)
      this.getParent().putMessage2("  " + msg);
  }

  /**
   * 取得全部消息。
   * 
   * @return 返回历史消息列表。
   */
  public List<String> getAllMessages() {
    return this.messages;
  }

  public String getCaption() {
    return caption;
  }

  public synchronized void setCaption(String caption) {
    this.caption = caption;
  }

  public float getMaxValue() {
    return maxValue;
  }

  public synchronized void setMaxValue(float maxValue) {
    this.maxValue = maxValue;
  }

  public float getMinValue() {
    return minValue;
  }

  public synchronized void setMinValue(float minValue) {
    this.minValue = minValue;
  }

  public String getMsgPrefix() {
    return msgPrefix;
  }

  public synchronized void setMsgPrefix(String msgPrefix) {
    this.msgPrefix = msgPrefix;
  }

  public float getParentStep() {
    return parentStep;
  }

  public synchronized void setParentStep(float parentStep) {
    this.parentStep = parentStep;
  }

  public float getPosition() {
    return position;
  }

  public synchronized void setPosition(float position) throws InterruptedException {
    if (position < this.minValue)
      position = this.minValue;
    if (position > this.maxValue)
      position = this.maxValue;
    float step = position - this.position;
    this.stepBy(step);
  }
  
  private Progress getParent() {
    try {
      int idx = stack.indexOf(this);
      return stack.get(idx - 1);
    } catch (Exception e) {
      return null;
    }
  }

}
